package com.eav.app.bluetoothsample

import android.Manifest
import android.app.Dialog
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothGatt
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.eav.lib.bluetooth.callback.BTConnCallBack
import com.eav.lib.bluetooth.callback.BTNotifyCallBack
import com.eav.lib.bluetooth.callback.BTScanCallBack
import com.eav.lib.bluetooth.callback.BTWriteCallBack
import com.eav.lib.bluetooth.exception.BTException
import com.eav.lib.bluetooth.gatt.*
import com.eav.lib.bluetooth.util.BTUtil
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.MainScope
import java.io.File

class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {

    var devices = arrayListOf<BluetoothDevice>()
    var mAdapater: BTAdapter? = null
    var mDevice: GattDevice? = null

    //private lateinit var dialog: QMUITipDialog
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        checkPermission()
        initView()
        tvVersion.text = "当前版本:${packageManager.getPackageInfo(packageName, 0).versionName}"
    }


    @Throws(Exception::class)
    fun showLoading(context: Context): Dialog {
        val dialog = QMUITipDialog.Builder(context)
            .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
            .setTipWord("扫描中")
            .create(false)
        dialog.show()
        return dialog
    }


    private fun checkPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
                || checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
                || checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
                || checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
            ) {
                requestPermissions(
                    arrayOf(
                        Manifest.permission.READ_EXTERNAL_STORAGE,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        Manifest.permission.ACCESS_COARSE_LOCATION,
                        Manifest.permission.ACCESS_FINE_LOCATION
                    ), 0x01
                )
            } else {
                LogCatHelper.dirPath = (Environment.getExternalStorageDirectory().absolutePath
                        + File.separator + "eav" + File.separator + "ble" + File.separator + "logger")
                LogCatHelper.start()
            }
        }
    }


    fun initView() {
        tvLogPath.text = "日志存储路径：/eav/ble/logger"
        GattScanApi.init(this, GattScanConfig().also {
            it.mScanTimeOut = 15 * 1000L
        })
        btnStartScan.setOnClickListener {
            //dialog = showLoading(this) as QMUITipDialog
            devices.clear()
            mAdapater?.notifyDataSetChanged()
            GattScanApi.startScan(object : BTScanCallBack {
                override fun onScanFailed(exception: BTException): Boolean {
                    Log.e(
                        "Main",
                        "exception code:${exception.exceptionCode} message:${exception.message}"
                    )
                    //dialog.dismiss()
                    exception.message?.run {
                        Toast.makeText(this@MainActivity, exception.message, Toast.LENGTH_SHORT)
                            .show()
                    }

                    return false
                }

                override fun onScanResult(device: BluetoothDevice) {
                    //dialog.dismiss()
                    if (!device.name.isNullOrEmpty()) {
                        devices.add(device)
                    }
                    mAdapater?.notifyDataSetChanged()
                }
            })
        }
        btnStopScan.setOnClickListener {
            GattScanApi.stopScan()
        }
        lvBluetooth.run {
            mAdapater = BTAdapter(this@MainActivity, devices)
            adapter = mAdapater
        }
        GattConnApi.init(this@MainActivity)
        lvBluetooth.setOnItemClickListener { parent, view, position, id ->
            devices[position].name?.let {
                //unicom蓝牙
                var gattDevice = GattDevice(
                    devices[position],
                    "12345678-1234-5678-1234-56789abcdef0",
                    "12345678-1234-5678-1234-56789abcdef1",
                    "12345678-1234-5678-1234-56789abcdef2"
                )
                /*//日本测绘器蓝牙
                var gattDevice = GattDevice(devices[position], "49535343-FE7D-4AE5-8FA9-9FAFD205E455"
                    , "49535343-1E4D-4BD9-BA61-23C647249616",
                    "49535343-1E4D-4BD9-BA61-23C647249616")*/
                /*//一代二代测绘器蓝牙
                var gattDevice = GattDevice(
                        devices[position],
                        "0003cdd0-0000-1000-8000-00805f9b0131",
                        "0003cdd2-0000-1000-8000-00805f9b0131",
                        "0003cdd1-0000-1000-8000-00805f9b0131"
                )*/
                var mtu = 512
                gattDevice?.run {
                    GattConnApi.connect(gattDevice, GattConnConfig().apply {
                        mRetryConnCount = 3
                        mMtu = mtu
                        mIsSplit = false
                    }, object : BTConnCallBack {
                        override fun onConnectFail(
                            device: BluetoothDevice,
                            exception: BTException
                        ): Boolean {
                            Log.e(
                                "Main",
                                "connect fail exception code:${exception.exceptionCode} message:${exception.message}"
                            )
                            exception.message?.run {
                                Toast.makeText(
                                    this@MainActivity,
                                    exception.message,
                                    Toast.LENGTH_SHORT
                                ).show()
                            }
                            return false
                        }

                        override fun onConnectSuccess(
                            bleDevice: BluetoothDevice,
                            gatt: BluetoothGatt?,
                            status: Int
                        ) {
                            Log.e("Main", "connect success")
                            tvDeviceName.text = "设备名称：${bleDevice.name}"
                            tvDeviceAddr.text = "设备mac：${bleDevice.address}"
                            tvState.text = "连接状态：已连接"
                            GattConnApi.notifyCharacteristic(gattDevice, object : BTNotifyCallBack {
                                override fun onNotifyFailure(
                                    device: BluetoothDevice,
                                    exception: BTException
                                ) {
                                }

                                override fun onCharacteristicChanged(
                                    device: BluetoothDevice,
                                    data: ByteArray
                                ) {
                                    Log.e(
                                        "Main",
                                        "${device.name} onCharacteristicChanged size:${data.size} hex:${
                                            BTUtil.formatHexString(
                                                data,
                                                true
                                            )
                                        }"
                                    )
                                    tvNotify.text = "收到数据长度：${data.size} 16进制格式:${
                                        BTUtil.formatHexString(
                                            data,
                                            true
                                        )
                                    }"
                                }
                            })
                            mDevice = gattDevice
                        }

                        override fun onDisConnected(
                            device: BluetoothDevice,
                            gatt: BluetoothGatt?,
                            status: Int
                        ) {
                            Log.e("Main", "disconnected status:$status")
                            tvState.text = "连接状态：断开"
                        }
                    })
                    write(gattDevice)

                }
            }

        }
        btnDisconnectAll.setOnClickListener {
            GattConnApi.disconnectAll()
            tvState.text = "连接状态：断开"
        }
    }

    fun write(gattDevice: GattDevice) {
        var array = ByteArray(1000)
        for (i in 0 until 1000) {
            array[i] = i.toByte()
        }
        GattConnApi.writeCharacteristic(gattDevice, array, object : BTWriteCallBack {
            override fun onWriteSuccess(
                bluetoothDevice: BluetoothDevice,
                current: Int,
                total: Int,
                justWrite: ByteArray
            ) {
                Log.e(
                    "Main",
                    "${bluetoothDevice.name} current:$current total:$total hex:${
                        BTUtil.formatHexString(
                            justWrite,
                            true
                        )
                    }"
                )
                tvWrite.text =
                    "写入数据长度:${justWrite.size} 16进制格式：${BTUtil.formatHexString(justWrite, true)}"
                if (current == total) {
                    write(gattDevice)
                }
            }

            override fun onWriteFailure(bluetoothDevice: BluetoothDevice, exception: BTException) {
                Log.e(
                    "Main",
                    "write failure excepitioncode:${exception.exceptionCode} length:${array.size}"
                )
            }
        })
    }
}
